package com.oceantrader.sale.biz.staff.dao;

import java.util.List;

import org.springframework.stereotype.Component;

import com.oceantrader.root.tools.Dao;
import com.oceantrader.root.tools.Dao.Transaction;
import com.oceantrader.root.tools.Sql;
import com.oceantrader.sale.biz.staff.entity.Staff;
import com.oceantrader.sale.biz.staff.pojo.StaffSearchParam;

import io.vertx.core.Future;
import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class StaffDao {
    private final Dao dao;

    public Future<Long> insert(Future<Transaction> tx, Staff param) {
        Sql sql = new Sql();
        sql.append("INSERT INTO `staff`(");
        if (param.getId() != null) {
            sql.append("`id`,");
        }
        sql.append("`code`,");
        sql.append("`nick`,");
        sql.append("`phone`,");
        sql.append("`username`,");
        sql.append("`password`,");
        sql.append("`create_datetime`,");
        sql.append("`create_staff_id`,");
        sql.append("`admin`,");
        sql.append("`enable`,");
        sql.ignore(",").append(") VALUES (");
        if (param.getId() != null) {
            sql.append("#{},", param.getId());
        }
        sql.append("#{},", param.getCode());
        sql.append("#{},", param.getNick());
        sql.append("#{},", param.getPhone());
        sql.append("#{},", param.getUsername());
        sql.append("#{},", param.getPassword());
        sql.append("#{},", param.getCreateDatetime());
        sql.append("#{},", param.getCreateStaffId());
        sql.append("#{},", param.getAdmin());
        sql.append("#{},", param.getEnable());
        sql.ignore(",").append(")");
        return dao.insert(tx, sql);
    }

    public Future<Integer> deleteByIdList(Future<Transaction> tx, List<Long> idList) {
        Sql sql = new Sql();
        sql.append("DELETE FROM `staff`");
        sql.append("WHERE");
        sql.append("`id` IN").forEachParams("(", idList, ",", ")");
        return dao.update(tx, sql);
    }

    public Future<Integer> updateById(Future<Transaction> tx, Staff param) {
        Sql sql = new Sql();
        sql.append("UPDATE `staff`");
        sql.append("SET");
        if (param.getCode() != null) {
            sql.append("`code`=#{},", param.getCode());
        }
        if (param.getNick() != null) {
            sql.append("`nick`=#{},", param.getNick());
        }
        if (param.getPhone() != null) {
            sql.append("`phone`=#{},", param.getPhone());
        }
        if (param.getUsername() != null) {
            sql.append("`username`=#{},", param.getUsername());
        }
        if (param.getPassword() != null) {
            sql.append("`password`=#{},", param.getPassword());
        }
        if (param.getCreateDatetime() != null) {
            sql.append("`create_datetime`=#{},", param.getCreateDatetime());
        }
        if (param.getCreateStaffId() != null) {
            sql.append("`create_staff_id`=#{},", param.getCreateStaffId());
        }
        if (param.getAdmin() != null) {
            sql.append("`admin`=#{},", param.getAdmin());
        }
        if (param.getEnable() != null) {
            sql.append("`enable`=#{},", param.getEnable());
        }
        sql.ignore(",");
        sql.append("WHERE `id`=#{}", param.getId());
        return dao.update(tx, sql);
    }

    private void select(Sql sql) {
        sql
                .append("SELECT")
                .append("`id` AS `id`,")
                .append("`code` AS `code`,")
                .append("`nick` AS `nick`,")
                .append("`phone` AS `phone`,")
                .append("`username` AS `username`,")
                .append("`password` AS `password`,")
                .append("`create_datetime` AS `createDatetime`,")
                .append("`create_staff_id` AS `createStaffId`,")
                .append("`admin` AS `admin`,")
                .append("`enable` AS `enable`,")
                .ignore(",")
                .append("FROM `staff`");
    }

    private void where(Sql sql, StaffSearchParam param) {
        sql.append("WHERE").ignore("AND");
        if (param.getCode() != null) {
            sql.append("AND `code`=#{}", param.getCode());
        }
        if (param.getCodeLikeR() != null) {
            sql.append("AND `code` LIKE #{}", Sql.likeR(param.getCodeLikeR()));
        }
        if (param.getNick() != null) {
            sql.append("AND `nick`=#{}", param.getNick());
        }
        if (param.getNickLike() != null) {
            sql.append("AND `nick` LIKE #{}", Sql.like(param.getNickLike()));
        }
        if (param.getPhone() != null) {
            sql.append("AND `phone`=#{}", param.getPhone());
        }
        if (param.getPhoneLikeR() != null) {
            sql.append("AND `phone` LIKE #{}", Sql.likeR(param.getPhoneLikeR()));
        }
        if (param.getEnable() != null) {
            sql.append("AND `enable`=#{}", param.getEnable());
        }
        sql.ignore("WHERE");
    }

    public Future<List<Staff>> selectList(Future<Transaction> tx, StaffSearchParam param) {
        Sql sql = new Sql();
        this.select(sql);
        this.where(sql, param);
        if (param.getLimit1() != null && param.getLimit2() != null) {
            sql.append("LIMIT #{},#{}", param.getLimit1(), param.getLimit2());
        }
        return dao.selectList(tx, sql, Staff.class);
    }

    public Future<Long> selectCount(Future<Transaction> tx, StaffSearchParam param) {
        Sql sql = new Sql();
        sql.append("SELECT COUNT(*) FROM `staff`");
        this.where(sql, param);
        return dao.selectOneColumn(tx, sql, Long.class);
    }

    public Future<Staff> selectById(Future<Transaction> tx, Long id) {
        Sql sql = new Sql();
        this.select(sql);
        sql.append("WHERE `id`=#{}", id);
        return dao.selectOne(tx, sql, Staff.class);
    }

    public Future<Staff> selectByUsername(Future<Transaction> tx, String username) {
        Sql sql = new Sql();
        this.select(sql);
        sql.append("WHERE `username`=#{}", username);
        return dao.selectOne(tx, sql, Staff.class);
    }
}
